package com.skyline.energy.executor.mongo;

import java.lang.reflect.Method;
import java.util.List;

import com.skyline.energy.definition.mongo.BaseMongoDefinition;
import com.skyline.energy.exception.DaoGenerateException;
import com.skyline.energy.executor.DataAccessExecutor;
import com.skyline.energy.mongo.MongoDataAccessor;
import com.skyline.energy.mongo.MongoShell;
import com.skyline.energy.utils.ArgumentUtils;

/**
 * Mongo操作调用方法抽象类
 * 
 * @author wuqh
 * 
 */
public abstract class AbstractMongoExecutor implements DataAccessExecutor {
	final MongoDataAccessor dataAccessor;
	protected BaseMongoDefinition definition;

	AbstractMongoExecutor(MongoDataAccessor dataAccessor, Method method) throws DaoGenerateException {
		this.dataAccessor = dataAccessor;
		initDefinition(method);
	}

	/**
	 * 初始化操作配置信息
	 * 
	 * @param method
	 * @throws DaoGenerateException
	 */
	protected abstract void initDefinition(Method method) throws DaoGenerateException;

	@Override
	public Object execute(Object obj, Object[] args) {
		// 获取需要用到的查询shell和参数
		String collectionName = definition.getCollectionName(args);
		String actualShell = definition.getShellWithToken();
		Object paramArray = getParamArray(args);
		logShell(actualShell);
		return dataAccess(collectionName, actualShell, paramArray);
	}

	protected Object getParamArray(Object[] args) {
		Method[] getterMethods = definition.getGetterMethods();
		Integer[] parameterIndexes = definition.getParameterIndexes();

		List<String> parameterNames = definition.getParsedShell().getParameterNames();
		Object[] paramArray = ArgumentUtils.fetchValues(getterMethods, parameterIndexes, args, parameterNames);
		
		return paramArray;
	}
	
	protected Object dataAccess(String collectionName, String actualShell, Object paramArray) {
		// 构造操作的数据结构
		MongoShell shell = new MongoShell(actualShell, (Object[]) paramArray);
		return doDataAccess(collectionName, shell);
	}
	
	protected void logShell(String actualShell) {
		
	}

	protected Object doDataAccess(String collectionName, MongoShell shell) {
		return null;
	}

}
